package com.gillion.grape.fros.ui.wizards;


import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.ZipFile;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.eclipse.core.internal.resources.Resource;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.wizards.datatransfer.ImportOperation;
import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider;
import org.osgi.framework.Bundle;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import com.gillion.grape.core.Logger;
import com.gillion.grape.fros.Activator;
import com.gillion.grape.fros.ui.util.FileUtil;
import com.gillion.grape.fros.ui.util.IOUtils;

/**
 * 新建一个fros工程
 * 
 * @author taiyuan
 * 20120807
 * 
 */
public class NewWEFProject {
	private String projectName;
	private String nameSpace;
	private String dbname;
	private String url;
	private String userName;
	private String password;
	private String driverClass;

	/**
	 * 
	 * @param projectName
	 */
	public NewWEFProject(String projectName,String nameSpace,String dbName,String url,String userName,String password,String driverClass) {
		this.projectName = projectName;
		this.nameSpace = nameSpace;
		this.dbname = dbName;
		this.url = url;
		this.userName = userName;
		this.password = password;
		this.driverClass = driverClass;
	}

	public void newProject() {
		IProject frosProject = ResourcesPlugin.getWorkspace().getRoot().getProject(this.projectName);
		if (frosProject.exists()) {
			return;
		}
		try {
			// 解压打包好的工程
			ZipFile zipFile = getZipFileFromPluginDir("/resource/fros.zip", Activator.getDefault().getBundle());
			importFilesFromZip(zipFile, frosProject.getFullPath(), null);
			
			// 导入工程配置
			
			IFile iFile = frosProject.getFile(".classpath");
			genFile(iFile,frosProject);
			
			IFile systemConfigFike = frosProject.getFile("config/systemConfig.properties");
			genFile(systemConfigFike,frosProject);
			
			IFile webFile = frosProject.getFile("WebContent/WEB-INF/web.xml");
			genFile(webFile,frosProject);
			
			IFile projectFile = frosProject.getFile(".project");
			genFile(projectFile,frosProject);
			
			IFile frosToolsFile = frosProject.getFile("Fros Tools - NetService.launch");
			genFile(frosToolsFile,frosProject);
			
			IFile jdbcFile = frosProject.getFile("config/jdbc.properties");
			genJdbcFile(jdbcFile,dbname,url,userName,password,driverClass);
			
				DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	            DocumentBuilder db = factory.newDocumentBuilder();
	            Document doc = db.parse(new File(frosProject.getFile(".grape").getLocation().makeAbsolute().toFile().getAbsolutePath()));
	            doc.getElementsByTagName("value").item(0).getFirstChild().setNodeValue(nameSpace);
	            doc.getElementsByTagName("value").item(2).getFirstChild().setNodeValue(this.projectName);
	            Source xmlSource = new DOMSource(doc);
	            TransformerFactory transFactory = TransformerFactory.newInstance();  
	            Transformer transformer = transFactory.newTransformer(); 
	            Result result = new StreamResult(new File(frosProject.getFile(".grape").getLocation().makeAbsolute().toFile().getAbsolutePath())); 
	            transformer.transform(xmlSource, result);
	            Logger.logInfo(frosProject.getFile(".grape").getFullPath() + " 生成成功!");
			
			frosProject.open(null);
			frosProject.refreshLocal(IResource.DEPTH_INFINITE, null);
		} catch (Exception e) {
			Logger.logError(e);
		}
	}

	// TODO 重新生成
		private void genFile(IFile iFile,IProject project) throws CoreException, IOException {
			String fileContent = IOUtils.toString(iFile.getContents(),iFile.getCharset());
			fileContent = fileContent.replaceAll("%projectName%", project.getName());
			ByteArrayInputStream byteInputStream = new ByteArrayInputStream(fileContent.getBytes(iFile.getCharset()));
			FileUtil.writeFile(byteInputStream, iFile);
		}
		
	// TODO 重新生成
		private void genJdbcFile(IFile iFile,String dbName,String url,String userName,String password,String driverClass) throws CoreException, IOException {
			String fileContent = IOUtils.toString(iFile.getContents(),iFile.getCharset());
			if("oracle".endsWith(driverClass)){
			fileContent = fileContent.replaceAll("%driverClass%", "oracle.jdbc.driver.OracleDriver");
			fileContent = fileContent.replaceAll("%url%", "jdbc:oracle:thin:@"+url+":1521:");
			}
			if("mysql".endsWith(driverClass)){
			fileContent = fileContent.replaceAll("%driverClass%", "com.mysql.jdbc.Driver");
			fileContent = fileContent.replaceAll("%url%", "jdbc:mysql://"+url+":3306/");
			}
			fileContent = fileContent.replaceAll("%dbName%", dbName);
			fileContent = fileContent.replaceAll("%userName%", userName);
			fileContent = fileContent.replaceAll("%password%", password);
			ByteArrayInputStream byteInputStream = new ByteArrayInputStream(fileContent.getBytes(iFile.getCharset()));
			FileUtil.writeFile(byteInputStream, iFile);
		}
	
	private ZipFile getZipFileFromPluginDir(String pluginRelativePath, Bundle pluginDescriptor) throws CoreException {
		try {
			URL starterURL = pluginDescriptor.getEntry(pluginRelativePath);
			return new ZipFile(FileLocator.toFileURL(starterURL).getFile());
		} catch (IOException e) {
			String message = pluginRelativePath + ": " + e.getMessage(); //$NON-NLS-1$
			Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, message, e);
			throw new CoreException(status);
		}
	}

	private void importFilesFromZip(ZipFile srcZipFile, IPath destPath, IProgressMonitor monitor)
			throws InvocationTargetException, InterruptedException {
		ZipFileStructureProvider structureProvider = new ZipFileStructureProvider(srcZipFile);
		ImportOperation op = new ImportOperation(destPath, structureProvider.getRoot(), structureProvider, null);
		op.run(monitor);
	}
}
